// 宏定义，防止多次引用报错
#ifndef YOLO_TEST_H
#define YOLO_TEST_H

// 导入头文件
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <string>
#include <vector>

/**
 * @brief 创建结果发布的结构体，包括边界框、类别名和置信度信息
 * 
 */
struct result{
    cv::Rect box;            // 边界框属性     
    std::string class_name;  // 类别名称属性
    int class_id;
    float confidence;        // 置信度属性
};

/**
 * @brief yolo检测类
 * 
 * 封装了基于OpenCV DNN的YOLOv8目标检测功能，支持ONNX模型格式
 * 主要功能包括模型初始化、图像预处理、目标检测以及结果可视化
 */
class yolo_detector{
    public:
    /**
     * @brief 结构体函数，初始基本参数
     */
    yolo_detector();

    /**
     * @brief 初始化函数，初始化ONNX模型
     * 
     * @param model_path:ONNX文件的路径
     * @return bool
     */
    bool initialize(const std::string& model_path);

    /**
     * @brief 检测函数，对图像目标进行检测
     * 
     * @param image_path:检测图像的路径
     * @return results:result结构体的集合
     */
    std::vector<result> detect(const cv::Mat& image);

    /**
     * @brief 在原本的图像上显示检测框
     * 
     * @param reslut:检测的最终结果
     * @param image_path:原始图象路径
     */
    void drawresluts(const cv::Mat& image ,std::vector<result> results);

    private:
    //基本参数
    cv::Size inputSize;                    // 输入图像尺寸
    std::vector<std::string> class_names;   // 类别名列表

    //OpenCV dnn模型
    cv::dnn::Net net;

    /**
     * @brief 预处理函数，进行图像预处理和归一化
     * 
     * @param image:目标图象
     * @result blob:神经网络
     */
    cv::Mat preprocess(const cv::Mat& image);

    /**
     * @brief 后处理函数
     * 
     * @param outputs:处理图像获得的原始数据
     * @param OriginalImageSize:原始图像的尺寸，用于检测框在原图的映射
     * @return 获得到的result数据
     */
    std::vector<result> postprocess(const cv::Mat& Output, const cv::Size& OriginalImageSize, float conf, float nms);
};

#endif //YOLO_TEST_H